﻿using eslib.nnp5.serializer;
using System;

namespace eslib.nnp5
{
    /// <summary>
    /// PkgHandler使用的中介数据包
    /// </summary>
    public class PkgHandlerAgentPkg : IPackage
    {
        #region 静态方法
        /// <summary>
        /// 创建新数据包
        /// </summary>
        /// <param name="obj">传递对象</param>
        /// <param name="serializeType">SerializedPkg的序列化方式</param>
        /// <returns></returns>
        public static PkgHandlerAgentPkg CreateNew<T>(T obj, SerializableType serializeType)
        {
            PkgHandlerAgentPkg spkg = new PkgHandlerAgentPkg(serializeType, obj);
            return spkg;
        }


        /// <summary>
        /// 以缓存转换包，错误时抛出异常
        /// </summary>
        /// <param name="buffer">数据包</param>
        /// <param name="serializeType">SerializedPkg的序列化方式</param>
        /// <returns></returns>
        public static PkgHandlerAgentPkg Transfer(byte[] buffer, SerializableType serializeType)
        {
            return GetSerializer(serializeType).Deserialize<PkgHandlerAgentPkg>(buffer);
        }

        static ISerializer GetSerializer(SerializableType type)
        {
            return type switch
            {
                SerializableType.json => new JsonSerializer(),
                SerializableType.xml => new ODATASerializer(),
                SerializableType.bson => new BsonSerializer(),
                _ => throw new ArgumentException()
            };
        }

        #endregion




        #region 数据成员

        /// <summary>
        /// 记录json对象的类型名
        /// </summary>
        public string TypeName { get; set; }

        /// <summary>
        /// class类型
        /// </summary>
        /// <returns></returns>
        public Type GetPkgType() => Type.GetType(TypeName);

        public enum SerializableType { xml = 0, json, bson }

        /// <summary>
        /// 序列化类型
        /// </summary>
        public SerializableType DataSerializeType { get; set; }


        /// <summary>
        /// 数据载体（保存序列化后的真正传递的数据）
        /// </summary>
        public byte[] Data { get; set; }



        /// <summary>
        /// 
        /// </summary>
        /// <param name="type"></param>
        /// <param name="data">以object装箱，但自身类型不能是object（影响反射时分析类型）</param>
        public PkgHandlerAgentPkg(SerializableType type, object data)
        {
            //序列化类型
            DataSerializeType = type;

            //记录class类型
            TypeName = data.GetType().AssemblyQualifiedName;

            //序列化
            Data = GetSerializer(DataSerializeType).Serialize(data);
        }

        public PkgHandlerAgentPkg()
        {
        }

        #endregion



        /// <summary>
        /// 根据typeName将json转换为对象
        /// </summary>
        /// <returns></returns>
        public object GetObject()
        {
            return GetSerializer(DataSerializeType).Deserialize(GetPkgType(), Data);
        }

        public T GetObject<T>() => (T)GetObject();



        public byte[] GetBuffer()
        {
            //整个SerializedPkg序列化
            return GetSerializer(DataSerializeType).Serialize(this);
        }

    }
}
